package com.durablemethods.futures.client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.rpc.IsSerializable;

public class NHLMarket implements Serializable, IsSerializable{
	private static final long serialVersionUID = 6989808308379630813L;
	private NHLTeam team;
	private List<NHLBidASk> bids = new ArrayList<NHLBidASk>();
	private Map<Double, List<NHLBidASk>> bidMap = new HashMap<Double, List<NHLBidASk>>();
	private Map<Double, List<NHLBidASk>> askMap = new HashMap<Double, List<NHLBidASk>>();
	private List<NHLBidASk> asks = new ArrayList<NHLBidASk>();
	private Double lastTrade;
	private NHLBidASk bidAskToProcess;
	private NHLTradeEntryDto tradeToProcess;
	public void setTeam(NHLTeam team) {
		this.team = team;
	}
	public NHLTeam getTeam() {
		return team;
	}
	public void addBidAsk(NHLBidASk bidAsk) {
		if (bidAsk.getVolume()<0){
			getAsks().add(bidAsk);
			Collections.sort(getAsks(), new OfferComparator());
			if (askMap.containsKey(bidAsk.getPrice())){
				List<NHLBidASk> list = askMap.get(bidAsk.getPrice());
				list.add(bidAsk);
			}else{
				List<NHLBidASk> newList = new ArrayList<NHLBidASk>();
				newList.add(bidAsk);
				askMap.put(bidAsk.getPrice(), newList);
			}
		}else if (bidAsk.getVolume()>0){
			getBids().add(bidAsk);			
			Collections.sort(getBids(), new BidComparator());
			if (bidMap.containsKey(bidAsk.getPrice())){
				List<NHLBidASk> list = bidMap.get(bidAsk.getPrice());
				list.add(bidAsk);
			}else{
				List<NHLBidASk> newList = new ArrayList<NHLBidASk>();
				newList.add(bidAsk);
				bidMap.put(bidAsk.getPrice(), newList);
			}
		}else{
			System.err.println("Slap dick is trying to execute a zero volume bidask");
		}
	}
	public String getAskLevel() {
		if (getAsks().size()>0){
			return getAsks().get(0).getPrice().toString();	
		}else{
			return "--";
		}
	}
	public String getBidLevel() {
		if (getBids().size()>0){
			return getBids().get(0).getPrice().toString();			
		}else{
			return "--";
		}
	}
	public String getBidSize() {
		if (getBids().size()>0){
			 Double price = getBids().get(0).getPrice();
			 Integer returnLevel = 0;
			 List<NHLBidASk> list = bidMap.get(price);
			 for (NHLBidASk nhlBidASk : list) {
				 returnLevel = returnLevel + nhlBidASk.getVolume();
			}
			return returnLevel.toString();
		}else{
			return "--";
		}
	}
	public String getAskSize() {
		if (getAsks().size()>0){
			 Double price = getAsks().get(0).getPrice();
			 Integer returnLevel = 0;
			 List<NHLBidASk> list = askMap.get(price);
			 for (NHLBidASk nhlBidASk : list) {
				 returnLevel = returnLevel + (nhlBidASk.getVolume() * -1);
			}
			return returnLevel.toString();
		}else{
			return "--";
		}
	}
	public boolean hasBids(){
		return !getBids().isEmpty();
	}
	public boolean hasOffer(){
		return !getAsks().isEmpty();
	}
	public Double getLastTrade() {
		if (lastTrade == null){
			return 0.0;
		}
		return lastTrade;
	}
	public void setLastTrade(Double lastTrade) {
		this.lastTrade = lastTrade;
	}
	
	class BidComparator implements Comparator<NHLBidASk>{

		@Override
		public int compare(NHLBidASk o1, NHLBidASk o2) {
			return o2.getPrice().compareTo(o1.getPrice());
		}
		
	}
	class OfferComparator implements Comparator<NHLBidASk>{
		
		@Override
		public int compare(NHLBidASk o1, NHLBidASk o2) {
			return o1.getPrice().compareTo(o2.getPrice());
		}
		
	}
	public void hitBid(String trader) {
		List<NHLBidASk> list = bidMap.get(getBids().get(0).getPrice());
		NHLBidASk nhlBidASk = list.get(0);

		NHLTrader sellTrader = new NHLTrader();
		sellTrader.setGoogleAccount(trader);
		NHLTradeEntryDto dto = new NHLTradeEntryDto();
		NHLTrader buyTraderTrader = new NHLTrader();
		buyTraderTrader.setGoogleAccount(nhlBidASk.getTraderName());
		
		dto.setBidAskId(nhlBidASk.getId());
		dto.setBuyer(buyTraderTrader);
		dto.setSeller(sellTrader);
		dto.setPrice(nhlBidASk.getPrice());
		dto.setShares(5);
		dto.setTeamId(nhlBidASk.getTeam().getId());
		bidAskToProcess = nhlBidASk;
		tradeToProcess = dto;
		list.remove(nhlBidASk);
		getBids().remove(nhlBidASk);				
	}
	public void liftOffer(String trader) {
		List<NHLBidASk> list = askMap.get(getAsks().get(0).getPrice());
		NHLBidASk nhlBidASk = list.get(0);

		NHLTrader buyTrader = new NHLTrader();
		buyTrader.setGoogleAccount(trader);
		NHLTradeEntryDto dto = new NHLTradeEntryDto();
		NHLTrader sellTrader = new NHLTrader();
		sellTrader.setGoogleAccount(nhlBidASk.getTraderName());
		
		dto.setBidAskId(nhlBidASk.getId());
		dto.setBuyer(buyTrader);
		dto.setSeller(sellTrader);
		dto.setPrice(nhlBidASk.getPrice());
		dto.setShares(5);
		dto.setTeamId(nhlBidASk.getTeam().getId());
		bidAskToProcess = nhlBidASk;
		tradeToProcess = dto;
		list.remove(nhlBidASk);
		getAsks().remove(nhlBidASk);
		
	}
	
	public String getBidTrader(){
		if (bids.size()>0){
		List<NHLBidASk> list = bidMap.get(getBids().get(0).getPrice());
		NHLBidASk nhlBidASk = list.get(0);
		return nhlBidASk.getTraderName();
		}else{
			return "--";
		}
		
	}
	public String getOfferTrader(){
		if (asks.size()>0){
			List<NHLBidASk> list = askMap.get(getAsks().get(0).getPrice());
			NHLBidASk nhlBidASk = list.get(0);
			return nhlBidASk.getTraderName();
			}else{
				return "--";
			}
	}
	
	
	public List<NHLBidASk> getBids() {
		return bids;
	}
	public void setBids(List<NHLBidASk> bids) {
		this.bids = bids;
	}
	public List<NHLBidASk> getAsks() {
		return asks;
	}
	public void setAsks(List<NHLBidASk> asks) {
		this.asks = asks;
	}
	public NHLTradeEntryDto getTradeToProcess() {
		return tradeToProcess;
	}
	public void setTradeToProcess(NHLTradeEntryDto tradeToProcess) {
		this.tradeToProcess = tradeToProcess;
	}
	public NHLBidASk getBidAskToProcess() {
		return bidAskToProcess;
	}
	public void setBidAskToProcess(NHLBidASk bidAskToProcess) {
		this.bidAskToProcess = bidAskToProcess;
	}

}
